<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-CN">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Microsoft YaHei:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|Microsoft YaHei:300,300italic,400,400italic,700,700italic|Inziu Iosevka Slab SC:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.2" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="Hexo, NexT" />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.2" />






<meta name="description" content="2017 12 01">
<meta property="og:type" content="article">
<meta property="og:title" content="2017 12 01">
<meta property="og:url" content="http://idmk.oschina.io/2017/12/01/2017-12-01/index.html">
<meta property="og:site_name" content="苦舟">
<meta property="og:description" content="2017 12 01">
<meta property="og:locale" content="zh-CN">
<meta property="og:updated_time" content="2017-11-30T17:39:33.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="2017 12 01">
<meta name="twitter:description" content="2017 12 01">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Gemini',
    sidebar: {"position":"left","display":"hide","offset":12,"offset_float":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://idmk.oschina.io/2017/12/01/2017-12-01/"/>





  <title>2017 12 01 | 苦舟</title>
  














</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-CN">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">苦舟</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">学海无涯，吾将上下求索。</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-commonweal">
          <a href="/404.html" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />
            
            公益404
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://idmk.oschina.io/2017/12/01/2017-12-01/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="东木金">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/uploads/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苦舟">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">2017 12 01</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2017-12-01T01:39:33+08:00">
                2017-12-01
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>2017 12 01<br><a id="more"></a></p>
<h2 id="20171226"><a href="#20171226" class="headerlink" title="20171226"></a>20171226</h2><p>基于规则来诊断心律失常：</p>
<ol>
<li>依赖于波识别出的位置的准确度。</li>
<li>必须密切结合其他临床资料，才能做出正确结论，如：临床症状、体征，既往史，X 线、超声、检验、动态心电图、运动心电图、CT、核磁共振、临床心电图检查，冠脉造影，手术经过等。也就是说，只分析心电图做出的诊断，正确率不会很高。那么我们这个系统的目标应该定为计算出特征、并告诉医生哪些特征不在标准值范围之内，可能患有什么疾病。</li>
</ol>
<h2 id="20171230"><a href="#20171230" class="headerlink" title="20171230"></a>20171230</h2><ol>
<li>掌握 A Wavelet Based ECG Delineator 的核心 idea。</li>
<li>分析 ecg-kit 做波识别的准确率。<ol>
<li>task_verify_ecg_kit.py</li>
</ol>
</li>
</ol>
<h3 id="分析-ecg-kit-做波识别的准确率"><a href="#分析-ecg-kit-做波识别的准确率" class="headerlink" title="分析 ecg-kit 做波识别的准确率"></a>分析 ecg-kit 做波识别的准确率</h3><p>在论文中使用的验证数据集上<br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="string">""" 验证 ecg-kit 识别波的能力 """</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">import</span> scipy.io <span class="keyword">as</span> sio</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">from</span> config.dataset_path_table <span class="keyword">import</span> the_qt_database_dir</div><div class="line"><span class="keyword">from</span> utils.ecg_feature <span class="keyword">import</span> WaveDelination</div><div class="line"></div><div class="line">LABEL = [<span class="string">'Pon'</span>, <span class="string">'P'</span>, <span class="string">'Poff'</span>, <span class="string">'QRSon'</span>, <span class="string">'Q'</span>, <span class="string">'R'</span>, <span class="string">'S'</span>, <span class="string">'QRSoff'</span>, <span class="string">'Ton'</span>, <span class="string">'T'</span>, <span class="string">'Toff'</span>]</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">read_ann</span><span class="params">(file_path)</span>:</span></div><div class="line">    ann = sio.loadmat(file_path)</div><div class="line">    <span class="keyword">return</span> ann</div><div class="line"></div><div class="line"><span class="keyword">for</span> folder, sub_folder, files <span class="keyword">in</span> os.walk(the_qt_database_dir()):</div><div class="line">    <span class="keyword">for</span> file <span class="keyword">in</span> files:</div><div class="line">        n_nan = <span class="number">0</span></div><div class="line">        <span class="keyword">if</span> file.endswith(<span class="string">r'delineation.mat'</span>):</div><div class="line">            file_path = folder + <span class="string">'/'</span> + file</div><div class="line">            ann = read_ann(file_path)</div><div class="line">            <span class="keyword">for</span> label <span class="keyword">in</span> LABEL:</div><div class="line">                n_nan += np.where(ann[<span class="string">'wavedet'</span>][<span class="string">'multilead'</span>]</div><div class="line">                                  [<span class="number">0</span>][<span class="number">0</span>][label][<span class="number">0</span>][<span class="number">0</span>][<span class="number">0</span>] == np.nan)[<span class="number">0</span>].shape[<span class="number">0</span>]</div><div class="line">        <span class="keyword">if</span> n_nan &gt; <span class="number">0</span>:</div><div class="line">            print(file_path)</div></pre></td></tr></table></figure></p>
<p>在从医院拿到的数据上<br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"><span class="string">""" 验证 ecg-kit 识别波的能力 """</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">import</span> scipy.io <span class="keyword">as</span> sio</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">from</span> config.dataset_path_table <span class="keyword">import</span> ecg_from_hospital_data_dir</div><div class="line"><span class="keyword">from</span> utils.ecg_feature <span class="keyword">import</span> WaveDelination</div><div class="line"></div><div class="line">LABEL = [<span class="string">"p_on"</span>, <span class="string">"p_peak"</span>, <span class="string">"p_off"</span>, <span class="string">"qrs_on"</span>, <span class="string">"qrs_peak"</span>, <span class="string">"qrs_off"</span>]</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">read_ann</span><span class="params">(file_path)</span>:</span></div><div class="line">    ann = sio.loadmat(file_path)</div><div class="line">    <span class="keyword">return</span> ann</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">with</span> open(<span class="string">'ecg-kit 在医院拿到的数据上做波识别的表现 .csv'</span>, <span class="string">'w'</span>) <span class="keyword">as</span> wfile:</div><div class="line">    print(<span class="string">' 一共多少个位置没识别出来 , 记录 '</span>, file=wfile)</div><div class="line">    <span class="keyword">for</span> folder, sub_folder, files <span class="keyword">in</span> os.walk(ecg_from_hospital_data_dir()):</div><div class="line">        <span class="keyword">for</span> file <span class="keyword">in</span> files:</div><div class="line">            <span class="keyword">if</span> file.endswith(<span class="string">r'delineation.mat'</span>):</div><div class="line">                n_nan = <span class="number">0</span></div><div class="line">                file_path = folder + <span class="string">'/'</span> + file</div><div class="line">                ann = WaveDelination(file_path).get_ann(<span class="string">"multilead"</span>)</div><div class="line">                <span class="keyword">for</span> label <span class="keyword">in</span> LABEL:</div><div class="line">                    n_nan += np.where(np.isnan(ann[label]))[<span class="number">0</span>].shape[<span class="number">0</span>]</div><div class="line">                <span class="keyword">if</span> n_nan &gt; <span class="number">0</span>:</div><div class="line">                    print(str(n_nan) + <span class="string">', '</span> + folder, file=wfile)</div></pre></td></tr></table></figure></p>
<h2 id="2017-年-12-月-31-日"><a href="#2017-年-12-月-31-日" class="headerlink" title="2017 年 12 月 31 日"></a>2017 年 12 月 31 日</h2><ol>
<li>基于 ecg-kit 未能识别的波的位置的个数，剔除个数较多的记录。</li>
<li>设法评估 ecg-kit 在剔除后的数据上识别出的波的位置的准确率。<br>因为论文《A Wavelet-Based ECG Delineator: Evaluation on Standard Databases》中说，<br>As for the delineation of the ECG waves, the mean and standard deviation of the differences between the automatic and manual annotations were computed. The mean error obtained with the WT approach was found not to exceed one sampling interval, while the standard deviations were around the accepted tolerances between expert physicians.<br>所以可以信任 ecg-kit 在论文中使用的测试集上，做出的波的识别具有很好的表现。因此只需评估 ecg-kit 在剔除后的数据上的表现。</li>
<li>如果 ecg-kit 在剔除后的数据上识别出的波的位置的准确率能够接受，那么继续做病的诊断；</li>
<li>否则设法提高准确率。</li>
</ol>
<h3 id="A-Wavelet-Based-ECG-Delineator-存在的缺点"><a href="#A-Wavelet-Based-ECG-Delineator-存在的缺点" class="headerlink" title="A Wavelet-Based ECG Delineator 存在的缺点"></a>A Wavelet-Based ECG Delineator 存在的缺点</h3><ol>
<li>依赖于从公开数据集中计算得到的特征规律，公开数据集包含的记录过少，并且从医院拿到的数据中的噪声比公开数据中的噪声更大，因此所使用的特征规律不一定适合医院拿到的数据；</li>
<li>依照特征规律本身存在一定的局限性，识别出的位置的正确性会随着噪声的变强而降低。</li>
</ol>
<p>下方的没识别出来的位置，指的是识别结果中波位置（on, peak, off）标为 nan 。因为 R 波波峰的识别相对简单，因此可以假定 ecg-kit 能找到每一个 R 波波峰。基于以上假定，统计没识别出来的位置的个数，可以得到 ecg-kit 没能找到的所有位置的个数。</p>
<h3 id="评估-ecg-kit-在剔除后的数据上的表现。"><a href="#评估-ecg-kit-在剔除后的数据上的表现。" class="headerlink" title="评估 ecg-kit 在剔除后的数据上的表现。"></a>评估 ecg-kit 在剔除后的数据上的表现。</h3><p>见报告：评估 ecg-kit 在少噪声的数据上做波识别的表现</p>
<h3 id="改进基于小波变换的算法"><a href="#改进基于小波变换的算法" class="headerlink" title="改进基于小波变换的算法"></a>改进基于小波变换的算法</h3><p>修改参数及策略<br>使用线性拟合的方法</p>
<p>代码：improve_wavelet_based_delineator.py</p>
<h2 id="2017-12-23"><a href="#2017-12-23" class="headerlink" title="2017-12-23"></a>2017-12-23</h2><ol>
<li>陈老师说医生做的诊断是 ground truth，致于为什么种类只有那么几种，这是因为只选了这几类的记录给我们。</li>
<li>在我写的代码中，utils.ecg_feature.py 代码里写的是特征的提取，所有诊断的代码写在 utils.diagnoise 包中，特征的格式看 example_EcgFeature.py ，判断窦性心律正常与否的代码写在 wave_segment_interval_measure.py ，用例在 example_normal_beat.py 。不懂得群里问。只有部分特征现在可用，看 example_EcgFeature.py 。</li>
<li>ecg-kit 做出的波的识别，存在大量的 nan ，且误差较大，故我将返回提高波识别的精度，你们继续写疾病的诊断。</li>
<li>对于复杂的疾病，我们先不做判断，也就是说，你们先看一看能不能通过写规则的方式来做判断，对困难的疾病先放着。后面会找医生标注数据。</li>
<li>如何评估自己写的诊断代码是否表现够好，打印一份列表，其中每条记录的格式为：病人标识 , 【是否患病，取值：不患当前病，患**病】<br>再打印一份列表，用于描述算法做出患病的诊断的原因，格式：<br>患病病人标识 1, 做出患病的诊断依据 1;<br>患病病人标识 2, 做出患病的诊断依据 2;<br>……</li>
</ol>
<h2 id="2017-12-19"><a href="#2017-12-19" class="headerlink" title="2017-12-19"></a>2017-12-19</h2><h2 id="ECG-项目-–-识别正常与不正常心跳"><a href="#ECG-项目-–-识别正常与不正常心跳" class="headerlink" title="ECG 项目 – 识别正常与不正常心跳"></a>ECG 项目 – 识别正常与不正常心跳</h2><p>需要添加的特征：<br>r_wave_amplitude, s_wave_amplitude, st_segment_width, time_qtc_interval</p>
<h2 id="2017-12-10"><a href="#2017-12-10" class="headerlink" title="2017-12-10"></a>2017-12-10</h2><p>工作汇报<br>这段时间的工作主要可以分为以下几个阶段：</p>
<ol>
<li>发现 ecg-kit 可以做波识别；</li>
<li>分析从医院拿到的数据，发现此数据中带了标注；</li>
<li>解读来自医院的数据，并构建读取数据的代码。</li>
</ol>
<p>详细：</p>
<ul>
<li>发现 ecg-kit 能够标识出各种波的起点，峰 / 谷，终点。</li>
<li>使用 ecg-kit 对 PTB 数据集做了波位置识别，检验了得到的波的个数与标注中波个数的差别，并抽样了部分数据，通过画图检验波位置标识是否足够好。</li>
<li>阅读 ecg-kit 此程序的文档。</li>
<li>拿到便携式心电检测设备，以及来自医院的数据。</li>
<li>设法使用 ecg-kit 识别来自医院的记录中的波，发现 ecg-kit 能读取 aECG(HL7) 格式的数据，但缺少关于记录的头文件和关于记录的波标注文件，就不能做波识别。也就是说， ecg-kit 只能在有波标注的情况下，才能做波标注，头文件与标注文件的格式与 MIT 数据集的格式相同，也就说可以使用 wfdb 这个程序包，生成头文件与标注文件。我按照相关文档生成了文档，且生成了一个空的标注文件，但没能成功使用 ecg-kit 实现波的识别。后面发现 aECG(HL7) 的数据自带了标注，于是暂停了使用 ecg-kit 做波识别。</li>
<li>通过阅读文档，解读 aECG(HL7) 格式的数据（来自医院的数据），并形成了说明文档。</li>
<li>构建了解析数据的代码。</li>
<li>提取数据，绘图验证数据标注的准确性和各个数据代表的意义，在观看绘图结果的情况下，数据的标注有偏差但是比较小，应该是可以接受的误差；</li>
<li>为了整个团队的协作效率更为高效，我到了玉泉的校区与团队的其他成员进行了会谈，交换了各自对这个项目掌握到的知识，做到了团队的每位成员现在对项目的认识是一致的。</li>
<li>阅读相关论文，发现现在很多分类正常或者不正常的研究，方法和我们类似，都是先提取特征，然后利用特征进行分类。不过大部分做的好的都是在二导联数据，十二导联的应该有很大空间可以做。</li>
<li>阅读诊断 ECG 的相关材料，得出对心跳做诊断需要考虑哪些特征。</li>
</ul>
<!--more-->
<h2 id="2017-12-08"><a href="#2017-12-08" class="headerlink" title="2017-12-08"></a>2017-12-08</h2><p>Softmax, Negative Sampling, and Noise Contrastive Estimation</p>
<h2 id="2017-12-03"><a href="#2017-12-03" class="headerlink" title="2017-12-03"></a>2017-12-03</h2><h3 id="WFDB-header-file-format"><a href="#WFDB-header-file-format" class="headerlink" title="WFDB header file format"></a>WFDB header file format</h3><p><a href="https://www.physionet.org/physiotools/wag/header-5.htm" target="_blank" rel="external">https://www.physionet.org/physiotools/wag/header-5.htm</a><br>a header file specifies the names of the associated signal files and their attributes.<br>Header files contain at a minimum a record line, which specifies the record name, the number of segments, and the number of signals.<br>Header files for ordinary records (those that contain one segment) also contain a signal specification line for each signal. Header files for multi-segment records (supported by WFDB library version 9.1 and later versions) contain a segment specification line for each segment.</p>
<h3 id="Record-line"><a href="#Record-line" class="headerlink" title="Record line"></a>Record line</h3><p>The first non-empty, non-comment line is the record line. It contains information applicable to all signals in the record. Its fields are, from left to right:</p>
<ul>
<li>record name<br>A string of characters that identify the record. The record name may include letters, digits and underscores ( ‘_’ ) only.</li>
<li>number of signals<br>Note that this is not necessarily equal to the number of signal files, since two or more signals can share a signal file. This number must not be negative; a value of zero is legal, however.</li>
<li>sampling frequency (in samples per second per signal) [optional]<br>This number can be expressed in any format legal for scanf(3) input of floating point numbers (thus ‘ 360 ’ , ‘ 360. ’ , ‘ 360.0 ’ , and ‘ 3.6e2 ’ are all legal and equivalent). The sampling frequency must be greater than zero; if it is missing, a value of 250 (DEFREQ, defined in <wfdb wfdb.h="">) is assumed.</wfdb></li>
<li>number of samples per signal [optional]<br>This field can be present only if the sampling frequency is also present. If it is zero or missing, the number of samples is unspecified and checksum verification of the signals is disabled.</li>
</ul>
<p>PS: <a href="https://www.physionet.org/physiotools/wag/header-5.htm#toc2" target="_blank" rel="external">官方文档</a> 还给了很多其他的可选字段，以上字段参考的 MIT 数据集中的字段。</p>
<h3 id="Signal-specification-lines"><a href="#Signal-specification-lines" class="headerlink" title="Signal specification lines"></a>Signal specification lines</h3><p>Each non-empty, non-comment line following the record line in a single-segment record contains specifications for one signal, beginning with signal 0. Header files must contain valid signal specification lines for at least as many signals as were indicated in the record line (the first non-empty, non-comment line in the file). Any extra signal specification lines are not read by WFDB library functions. From left to right in each line, the fields are:</p>
<ul>
<li>file name<br>The name of the file in which samples of the signal are kept. The environment variable WFDB (the database path) lists the directories in which signal files (as well as WFDB header and annotation files) are found; normally WFDB should include an initial empty component, so that signal files can be kept in any directory if they are designated by absolute path names in the header file. If the file name specifies that the signal file is to be found in a directory that is not already in WFDB, that directory is appended to the end of WFDB (by functions that read header files in WFDB library version 6.2 and later versions). Although the record name is usually part of the signal file name, this convention is not a requirement (see, e.g., examples 3, 4, and 5 below). Note that several signals can share the same file (i.e., they can belong to the same signal group); all entries for signals that share a given file must be consecutive, however. The file name ‘ - ’ refers to the standard input or output. The sum of the lengths of the file name and description fields (see below) is limited to 80 characters.</li>
<li>format<br>This field is an integer that specifies the storage format of the signal. All signals in a given group are stored in the same format. The most common formats are format 8 (eight-bit first differences) and format 16 (sixteen-bit amplitudes); see signal(5) (or <wfdb wfdb.h="">) for a list of other supported formats. The following three optional fields, if present, are bound to the format field (i.e., not separated from it by whitespace); they may be considered as format modifiers, since they further describe the encoding of samples within the signal file.<br><strong>Format 212</strong><br>Each sample is represented by a 12-bit two ’ s complement amplitude. The first sample is obtained from the 12 least significant bits of the first byte pair (stored least significant byte first). The second sample is formed from the 4 remaining bits of the first byte pair (which are the 4 high bits of the 12-bit sample) and the next byte (which contains the remaining 8 bits of the second sample). The process is repeated for each successive pair of samples. Most of the signal files in PhysioBank are written in format 212.<br>PS: 这里所说的信号貌似是模拟信号，因为模拟信号才考虑信号的取值范围。参看 MIT 数据集，此字段取 212 。</wfdb></li>
</ul>
<h2 id="2017-12-02"><a href="#2017-12-02" class="headerlink" title="2017-12-02"></a>2017-12-02</h2><h3 id="标准心电图纸"><a href="#标准心电图纸" class="headerlink" title="标准心电图纸"></a>标准心电图纸</h3><p>心电图坐标纸的横轴代表以毫秒 (ms) 为单位的时间，而纵轴代表振幅即以毫伏 (mV) 为单位的电压。横轴上每 1 个小格为 40ms；每 5 个小格（1 个大格）为 200ms。纵轴上 2 个大格的距离被标定代表 1mV，虽然如此，心电图的波形通常是用高度的单位 mm 而并不是强度的单位 mV 来描述。</p>
<h3 id="HL7-aECG-Implementation-Guide"><a href="#HL7-aECG-Implementation-Guide" class="headerlink" title="HL7 aECG Implementation Guide"></a>HL7 aECG Implementation Guide</h3><p>HL7 aECG Implementation Guide</p>
<h2 id="2017-12-01"><a href="#2017-12-01" class="headerlink" title="2017-12-01"></a>2017-12-01</h2><h3 id="处理从医院拿到的-ECG-数据"><a href="#处理从医院拿到的-ECG-数据" class="headerlink" title="处理从医院拿到的 ECG 数据"></a>处理从医院拿到的 ECG 数据</h3><ol>
<li><p>解压文件</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> config</div><div class="line"><span class="keyword">import</span> config.common <span class="keyword">as</span> comconfig</div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">import</span> zipfile</div><div class="line"><span class="keyword">from</span> tqdm <span class="keyword">import</span> tqdm</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">for</span> folder, subfolder, files <span class="keyword">in</span> tqdm(os.walk(comconfig.ecg_3k_data_dir())):</div><div class="line">    <span class="keyword">for</span> fl <span class="keyword">in</span> files:</div><div class="line">        <span class="keyword">if</span> fl.endswith(<span class="string">'.zip'</span>):</div><div class="line">            zip_filepath = os.path.join(folder, fl)</div><div class="line">            zip_file = zipfile.ZipFile(zip_filepath)</div><div class="line">            <span class="keyword">for</span> names <span class="keyword">in</span> zip_file.namelist():</div><div class="line">                zip_file.extract(names, folder)</div><div class="line">            zip_file.close()</div></pre></td></tr></table></figure>
</li>
<li><p>查找重复</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> config</div><div class="line"><span class="keyword">import</span> config.common <span class="keyword">as</span> comconfig</div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">import</span> zipfile</div><div class="line"><span class="keyword">from</span> xml.etree.ElementTree <span class="keyword">import</span> parse <span class="keyword">as</span> xmlparse</div><div class="line"></div><div class="line">name2cnt = &#123;&#125;</div><div class="line"></div><div class="line"><span class="keyword">for</span> folder, subfolder, files <span class="keyword">in</span> os.walk(comconfig.ecg_3k_data_dir()):</div><div class="line">    <span class="keyword">for</span> fl <span class="keyword">in</span> files:</div><div class="line">        <span class="keyword">if</span> fl.endswith(<span class="string">'xml'</span>):</div><div class="line">            filepath = os.path.join(folder, fl)</div><div class="line">            <span class="keyword">with</span>  open(filepath, <span class="string">'r'</span>) <span class="keyword">as</span> rf:</div><div class="line">                <span class="keyword">for</span> line <span class="keyword">in</span> rf.readlines():</div><div class="line">                    line = line.strip()</div><div class="line">                    <span class="keyword">if</span> line.startswith(<span class="string">'&lt;PatientName&gt;'</span>):</div><div class="line">                        pname = line</div><div class="line">                        name2cnt[pname] = name2cnt.get(pname, <span class="number">0</span>) + <span class="number">1</span></div><div class="line">print(name2cnt)</div></pre></td></tr></table></figure>
</li>
<li><p>xml 解析</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> config</div><div class="line"><span class="keyword">import</span> config.common <span class="keyword">as</span> comconfig</div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">try</span>:</div><div class="line">    <span class="keyword">import</span> xml.etree.cElementTree <span class="keyword">as</span> ET</div><div class="line"><span class="keyword">except</span> ImportError:</div><div class="line">    <span class="keyword">import</span> xml.etree.ElementTree <span class="keyword">as</span> ET</div><div class="line"></div><div class="line"><span class="keyword">for</span> folder, subfolder, files <span class="keyword">in</span> os.walk(comconfig.ecg_st1_data_dir()):</div><div class="line">    <span class="keyword">for</span> fl <span class="keyword">in</span> files:</div><div class="line">        <span class="keyword">if</span> fl.endswith(<span class="string">'xml'</span>):</div><div class="line">            filepath = os.path.join(folder, fl)</div><div class="line">            parser = ET.XMLParser(encoding=<span class="string">'GB2312'</span>)</div><div class="line">            rf = open(filepath, encoding=<span class="string">'GB2312'</span>)</div><div class="line">            tree = ET.parse(rf, parser)</div><div class="line">            root = tree.getroot()</div><div class="line"></div><div class="line">            pname = tree.find(<span class="string">'PatientInfo/PatientName'</span>).text</div><div class="line">            print(pname)</div><div class="line">            exit()</div></pre></td></tr></table></figure>
</li>
<li><p>获取特征</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> config.common <span class="keyword">as</span> comconfig</div><div class="line"><span class="keyword">import</span> os</div><div class="line"><span class="keyword">try</span>:</div><div class="line">    <span class="keyword">import</span> xml.etree.cElementTree <span class="keyword">as</span> ET</div><div class="line"><span class="keyword">except</span> ImportError:</div><div class="line">    <span class="keyword">import</span> xml.etree.ElementTree <span class="keyword">as</span> ET</div><div class="line"></div><div class="line">ns = &#123;<span class="string">'ns'</span>: <span class="string">'urn:hl7-org:v3'</span>&#125;</div><div class="line"></div><div class="line"><span class="keyword">for</span> folder, subfolder, files <span class="keyword">in</span> os.walk(comconfig.ecg_st1_data_dir()):</div><div class="line">    <span class="keyword">for</span> fl <span class="keyword">in</span> files:</div><div class="line">        <span class="keyword">if</span> fl.endswith(<span class="string">'aECG'</span>):</div><div class="line">            filepath = os.path.join(folder, fl)</div><div class="line">            tree = ET.parse(filepath)</div><div class="line">            root = tree.getroot()</div><div class="line">            <span class="comment"># effectiveTime_low = root.find(</span></div><div class="line">            <span class="comment">#     'ns:effectiveTime/ns:low', namespaces=ns)</span></div><div class="line">            <span class="comment"># effectiveTime_high = root.find(</span></div><div class="line">            <span class="comment">#     'ns:effectiveTime/ns:high', namespaces=ns)</span></div><div class="line"></div><div class="line">            <span class="comment"># patiant_info = root.find(</span></div><div class="line">            <span class="comment">#     'ns:componentOf/ns:timepointEvent/ns:componentOf/ns:subjectAssignment/ns:subject/ns:trialSubject', ns)</span></div><div class="line">            <span class="comment"># patiant_id = patiant_info.find('ns:id', ns).get('extension')</span></div><div class="line">            <span class="comment"># patiant_sub_info = patiant_info.find('ns:subjectDemographicPerson', ns)</span></div><div class="line">            <span class="comment"># patiant_name = patiant_sub_info.find('ns:name', ns).text</span></div><div class="line">            <span class="comment"># patiant_gender = patiant_sub_info.find(</span></div><div class="line">            <span class="comment">#     'ns:administrativeGenderCode', ns).get['code']</span></div><div class="line">            <span class="comment"># patiant_birthTime = patiant_sub_info.find(</span></div><div class="line">            <span class="comment">#     'ns:birthTime', ns).get['value']</span></div><div class="line"></div><div class="line">            annotation_set_ret = []</div><div class="line">            annotation_set_anchor = root.find(</div><div class="line">                <span class="string">'ns:component/ns:series/ns:subjectOf/ns:annotationSet'</span>, ns)</div><div class="line">            annotation_set = annotation_set_anchor.findall(<span class="string">'ns:component/ns:annotation'</span>, ns)</div><div class="line"></div><div class="line">            <span class="keyword">for</span> annotation <span class="keyword">in</span> annotation_set:</div><div class="line">                value_elem = annotation.find(<span class="string">'ns:value'</span>, ns)</div><div class="line">                <span class="keyword">if</span> value_elem <span class="keyword">is</span> <span class="keyword">not</span> <span class="keyword">None</span>:</div><div class="line">                    code = annotation.find(<span class="string">'ns:code'</span>, ns).get(<span class="string">'code'</span>)</div><div class="line">                    value = value_elem.get(<span class="string">'value'</span>)</div><div class="line">                    unit = value_elem.get(<span class="string">'unit'</span>)</div><div class="line">                    annotation_set_ret.append(</div><div class="line">                        &#123;<span class="string">'code'</span>: code, <span class="string">'value'</span>: value, <span class="string">'unit'</span>: unit&#125;)</div><div class="line"></div><div class="line">                component_elem = annotation.find(<span class="string">'ns:component'</span>, ns)</div><div class="line">                <span class="keyword">if</span> component_elem <span class="keyword">is</span> <span class="keyword">not</span> <span class="keyword">None</span>:</div><div class="line">                    annotation2 = component_elem.find(<span class="string">'ns:annotation'</span>, ns)</div><div class="line">                    code = annotation2.find(<span class="string">'ns:code'</span>, ns).get(<span class="string">'code'</span>)</div><div class="line">                    value = annotation2.find(<span class="string">'ns:value'</span>, ns).text</div><div class="line">                    annotation_set_ret.append(</div><div class="line">                        &#123;<span class="string">'code'</span>: code, <span class="string">'value'</span>: value&#125;)</div><div class="line"></div><div class="line"></div><div class="line">            print(annotation_set_ret)</div><div class="line">            exit()</div></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="comparison-of-different-optimizers"><a href="#comparison-of-different-optimizers" class="headerlink" title="comparison of different optimizers"></a>comparison of different optimizers</h3><p>01:40:05<br>“ RMSprop is an extension of Adagrad that deals with its radically diminishing learning rates. It is<br>identical to Adadelta, except that Adadelta uses the RMS of parameter updates in the<br>numerator update rule. Adam, finally, adds bias-correction and momentum to RMSprop. Insofar,<br>RMSprop, Adadelta, and Adam are very similar algorithms that do well in similar circumstances.<br>Kingma et al. [15] show that its bias-correction helps Adam slightly outperform RMSprop<br>towards the end of optimization as gradients become sparser. Insofar, Adam might be the best<br>overall choice. ”</p>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/11/28/Weight-Initialization-for-Deep-Networks/" rel="next" title="Weight Initialization for Deep Networks">
                <i class="fa fa-chevron-left"></i> Weight Initialization for Deep Networks
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/12/08/2017-12-08-关于团队协作-我要去跟团队成员讲什么/" rel="prev" title="2017 12 08 关于团队协作 我要去跟团队成员讲什么">
                2017 12 08 关于团队协作 我要去跟团队成员讲什么 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/uploads/avatar.jpg"
               alt="东木金" />
          <p class="site-author-name" itemprop="name">东木金</p>
           
              <p class="site-description motion-element" itemprop="description">正在学习机器学习，希望能变得很强！</p>
          
        </div>
        <nav class="site-state motion-element">

          
            <div class="site-state-item site-state-posts">
              <a href="/archives/">
                <span class="site-state-item-count">162</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-categories">
              <a href="/categories/index.html">
                <span class="site-state-item-count">18</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-tags">
              <a href="/tags/index.html">
                <span class="site-state-item-count">42</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/bdmk" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                    
                      GitHub
                    
                </a>
              </span>
            
              <span class="links-of-author-item">
                <a href="mailto:catcherchan94@outlook.com" target="_blank" title="E-Mail">
                  
                    <i class="fa fa-fw fa-envelope"></i>
                  
                    
                      E-Mail
                    
                </a>
              </span>
            
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#20171226"><span class="nav-number">1.</span> <span class="nav-text">20171226</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#20171230"><span class="nav-number">2.</span> <span class="nav-text">20171230</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#分析-ecg-kit-做波识别的准确率"><span class="nav-number">2.1.</span> <span class="nav-text">分析 ecg-kit 做波识别的准确率</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-年-12-月-31-日"><span class="nav-number">3.</span> <span class="nav-text">2017 年 12 月 31 日</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#A-Wavelet-Based-ECG-Delineator-存在的缺点"><span class="nav-number">3.1.</span> <span class="nav-text">A Wavelet-Based ECG Delineator 存在的缺点</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#评估-ecg-kit-在剔除后的数据上的表现。"><span class="nav-number">3.2.</span> <span class="nav-text">评估 ecg-kit 在剔除后的数据上的表现。</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#改进基于小波变换的算法"><span class="nav-number">3.3.</span> <span class="nav-text">改进基于小波变换的算法</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-23"><span class="nav-number">4.</span> <span class="nav-text">2017-12-23</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-19"><span class="nav-number">5.</span> <span class="nav-text">2017-12-19</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ECG-项目-–-识别正常与不正常心跳"><span class="nav-number">6.</span> <span class="nav-text">ECG 项目 – 识别正常与不正常心跳</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-10"><span class="nav-number">7.</span> <span class="nav-text">2017-12-10</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-08"><span class="nav-number">8.</span> <span class="nav-text">2017-12-08</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-03"><span class="nav-number">9.</span> <span class="nav-text">2017-12-03</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#WFDB-header-file-format"><span class="nav-number">9.1.</span> <span class="nav-text">WFDB header file format</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Record-line"><span class="nav-number">9.2.</span> <span class="nav-text">Record line</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Signal-specification-lines"><span class="nav-number">9.3.</span> <span class="nav-text">Signal specification lines</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-02"><span class="nav-number">10.</span> <span class="nav-text">2017-12-02</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#标准心电图纸"><span class="nav-number">10.1.</span> <span class="nav-text">标准心电图纸</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#HL7-aECG-Implementation-Guide"><span class="nav-number">10.2.</span> <span class="nav-text">HL7 aECG Implementation Guide</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2017-12-01"><span class="nav-number">11.</span> <span class="nav-text">2017-12-01</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#处理从医院拿到的-ECG-数据"><span class="nav-number">11.1.</span> <span class="nav-text">处理从医院拿到的 ECG 数据</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#comparison-of-different-optimizers"><span class="nav-number">11.2.</span> <span class="nav-text">comparison of different optimizers</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy;  2017 - 
  <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">东木金</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Gemini
  </a>
</div>


        

        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.2"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.2"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.2"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.2"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.2"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.2"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.2"></script>



  


  




	





  





  






  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'manual') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>





  

  

  

  
  
    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
          processEscapes: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
        }
      });
    </script>

    <script type="text/x-mathjax-config">
      MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for (i=0; i < all.length; i += 1) {
          all[i].SourceElement().parentNode.className += ' has-jax';
        }
      });
    </script>
    <script type="text/javascript" src="//cdn.bootcss.com/mathjax/2.7.1/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
  


  

  

</body>
</html>
